#include "defines.h"
#include "lib.h"
#include "kozos.h"
#include "nic.h"
#include "net.h"

typedef struct {
    uint8 li_vn_mode;
    uint8 stratum;
    uint8 poll;
    uint8 precision;
    uint32 root_delay;
    uint32 root_dispe;
    uint32 ref_id;
    uint32 ref_time_h;
    uint32 ref_time_l;
    uint32 orig_time_h;
    uint32 orig_time_l;
    uint32 recv_time_h;
    uint32 recv_time_l;
    uint32 tran_time_h;
    uint32 tran_time_l;
} sntp_packet;

static const uint8 src_IP[] = {192, 168, 0, 10};
static const uint8 dst_IP[] = {192, 168, 0, 2};

int sntptest_main(int argc, char *argv[])
{
    static net_params params;
    net_params *np = &params;
    uint8 *buffer = kz_kmalloc(512);
    ethernet_header *ehdr = (ethernet_header *)buffer;
    arp_packet *apacket = (arp_packet *)(buffer + sizeof(*ehdr));
    ip_header *ihdr = (ip_header *)(buffer + sizeof(*ehdr));
    udp_header *uhdr = (udp_header *)((uint8 *)ihdr + sizeof(*ihdr));
    sntp_packet *sp = (sntp_packet *)((uint8 *)uhdr + sizeof(udp_header));

    nic_init();

    nic_MAC(np->src_MAC);
    memcpy(np->src_IP, src_IP, 4);
    memcpy(np->dst_IP, dst_IP, 4);
    mac_get(buffer, np);
    np->src_port = 123;
    np->dst_port = 123;

    memset(sp, 0, sizeof(*sp));
    sp->li_vn_mode = 0x23;

    send_by_udp(buffer, sizeof(sntp_packet), np);

    // ARP & PING応答
    while (1) {
        if (frame_receive(buffer) == 0) {

            if ((ehdr->eth_ethernet_type == 0x0806)
                    && !memcmp(apacket->arp_dst_IP, src_IP, 4)
                    && (apacket->arp_operation == 1))
            {

                arp_reply(buffer, np);

            } else if ((ehdr->eth_ethernet_type == 0x0800)
                    && !memcmp(ihdr->ip_dst_IP, src_IP, 4)
                    && (ihdr->ip_protocol == 17)
                    && (uhdr->udp_dst_port == 123))
            {

                uint32 t;
                uint16 s, m, h;

                t = sp->tran_time_h;
                t = divmod(t, 60, &s);
                t = divmod(t, 60, &m);
                t += 9; // 時差
                t = divmod(t, 24, &h);
                putval(h, 2);
                puts(":");
                putval(m, 2);
                puts(":");
                putval(s, 2);
                puts("\n");
                break;

            }

        }
    }

    kz_kmfree(buffer);

    kz_reset();

    return 0;
}
